
#include <windows.h>
#include <gdiplus.h>

#define assert(a, b) 
#include "tileui.h"
#include "rand.h"

namespace TileUI
{

//this code uses GDI+, which needs one-time init and teardown running.
static ULONG_PTR gdiplusToken;
void StaticCreate()
{
	Gdiplus::GdiplusStartupInput s;
	Gdiplus::GdiplusStartup(&gdiplusToken, &s, NULL);
}

void StaticDestroy()
{
	Gdiplus::GdiplusShutdown(gdiplusToken);
}

class List
{
private:
	Gdiplus::Region m_clip;
	Gdiplus::SolidBrush m_fill;
	Gdiplus::RectF* m_rects;
	int m_count;
	Allocator* mpHeap;

	int mOriginX, mOriginY;

public:
	List(int x, int y, int h, int w, int rh, int pad, Allocator* pHeap)
		: m_fill(Gdiplus::Color(0, 162, 232))
		, m_clip(Gdiplus::Rect(0,0,w,h))
		, m_count( (h/(rh + pad)) +1)
		, mOriginX(x)
		, mOriginY(y)
	{
		//cache enough rectangles to give the illusion of an entire wheel
		m_rects = static_cast<Gdiplus::RectF*>(pHeap->allocate(sizeof(Gdiplus::RectF)*m_count));

		for(int i=0; i<m_count; ++i)
		{
			m_rects[i] = Gdiplus::RectF(float(pad), float(i*(rh+pad)), float(w-pad), float(rh));
		}
	}

	~List()
	{
		mpHeap->deallocate(m_rects);
	}

	void Draw(Gdiplus::Graphics& graphics)
	{
		//save clip 
		Gdiplus::Region clip;
		graphics.GetClip(&clip);

		graphics.TranslateClip(mOriginX, mOriginY);
		graphics.TranslateTransform(mOriginX, mOriginY);

		//draw boxes
		graphics.SetClip(&m_clip, Gdiplus::CombineModeReplace);
		graphics.FillRectangles(&m_fill, m_rects, m_count);

		//restore clip
		graphics.TranslateClip( 0, 0 );
		graphics.SetClip(&clip, Gdiplus::CombineModeReplace);

		//reset transform
		Gdiplus::Matrix m;
		graphics.SetTransform(&m);		
	};

	void HitTest(int x, int y)
	{
	};

};


//groups of 4 points defining a bezier.


//err... this might end up being the Paint() call...
void TestPaint(win32hdc dc, Allocator* pHeap)
{
	Gdiplus::Graphics g(static_cast<HDC>(dc));

	Gdiplus::SolidBrush black(Gdiplus::Color(0,0,0));
	Gdiplus::Pen white(Gdiplus::Color(180,255,255,255), 4.0);

	Gdiplus::RectF screen(0,0,700,500);
	g.FillRectangle(&black, screen);
	

	//some prettyness
	{
		const int kNumCurves = 32;
		Random::PRNG rand(32, 100);

		g.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);

		for(int i=0; i<kNumCurves; ++i)
		{
			Gdiplus::PointF curves[4];
			float scale = 200.0f;

			curves[0] = Gdiplus::PointF(10.0f, 10.0f);
			curves[1] = Gdiplus::PointF(200.0f + rand.randf()*scale, 200.0f + rand.randf()*scale);
			curves[2] = Gdiplus::PointF(300.0f + rand.randf()*scale, 300.0f + rand.randf()*scale);
			curves[3] = Gdiplus::PointF(690.0f, 490.0f);

			g.DrawBeziers(&white, curves, 4);
		}

		g.SetSmoothingMode(Gdiplus::SmoothingModeDefault);
	}

	List l(10, 10, 480, 120, 100, 10, pHeap);
	l.Draw(g);

	List l2(130, 10, 480, 140, 50, 8, pHeap);
	l2.Draw(g);

	Gdiplus::SolidBrush overlay(Gdiplus::Color(200, 0,0,0));
	Gdiplus::RectF overlays[2];
	overlays[0] = Gdiplus::RectF(300.0f, 10.0f, 370.0f, 100.0f);
	overlays[1] = Gdiplus::RectF(300.0f, 150.0f, 370.0f, 320.0f);
	g.FillRectangles( &overlay, overlays, 2); 
//	g.DrawRectangles( &white, overlays, 2);
}

}